﻿#define _CRT_SECURE_NO_WARNINGS
// ↑ 将本行在代码放在第一行可以避免 scanf的报错问题（仅在VS编译器里）
//【初阶】10.STL+string
//【初阶】11.string(1)

//【头文件包含】
//C++的主要头文件
#include<iostream>//c++的输入输出流
using std::cout, std::endl,std::cin;

//使用string需要包含的头文件和引入的类
#include<string>
using std::string;

//C的主要头文件
//#include<stdio.h>
//#include<stdlib.h>
//#include<assert.h>
//#include<string.h> 




//【命名空间】

//【结构体声明】【类声明】



//【函数声明】
void Test1();void Test2();void Test3();


//【主函数】
int main()
{
	
	Test1();
	Test2();
	Test3();
	
	cout << "****主函数结束****" << endl;
	return 0;
}

//【函数定义】


/*测试用例*/void Test1()
{

	cout << "****测试用例开始****"<< endl;
	//构造
	string s1;//无参构造
	string s2("hello");//带参构造
	string s3(s2);//拷贝构造
	string s4(10, 'a');//指定参数构造
	//另外两种拷贝构造
	string s5 = "hello";
	string s6 = s5;

	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;
	cout << s4 << endl;
	cout << s5 << endl;
	cout << s6 << endl;

	s1 = s2;//赋值
	cout << s1 << endl;

	//插入
	s1.push_back('z');//字符插入
	cout << s1 << endl;
	s1.append("abcde");//字符串插入
	cout << s1 << endl;
	s1 += '1';//字符插入
	cout << s1 << endl;
	s1 += "2345";//字符串插入
	cout << s1 << endl;
	for (int i = 0;i < s1.size();++i)
	{
		cout << s1[i] << " ";
	}
	cout << endl;

	

	cout << "****测试用例结束****" << endl << endl;

}

/*测试用例*/void Test2()
{
	cout << "****测试用例开始****" << endl;
	string s1("helloworld");
	cout << s1 << endl;
	//拷贝指定位置长度的字符串
	string s2(s1, 2, 2);
	cout << s2 << endl;
	string s3(s1, 4, string::npos);
	cout << s3 << endl;

	
	//迭代器遍历
	string::iterator it = s1.begin();
	while (it != s1.end())
	{
		*it -= 1;
		cout << *it << " ";
		++it;
	}
	cout << endl;
	//auto遍历
	for (auto ch : s1)
	{
		ch += 1;
		cout << ch <<" ";
	}
	cout << endl;
	cout << "****测试用例结束****" << endl<<endl;
}

/*测试用例*/void Test3()
{
	cout << "****测试用例开始****" << endl;
	string s1("hello world");
	string s2("hello");
	cout <<s1<< " size=" << s1.size() <<" length=" << s1.length() << endl;
	cout <<s2<< " size=" << s2.size() <<" length=" << s2.length() << endl;
	cout << s1.capacity() << endl;
	cout << s2.capacity() << endl;
	cout << s1.empty() << endl;
	s1.clear();
	cout << s1.empty() << endl;

	//指定位置插入
	s2.insert(s2.begin(),'0');
	cout << s2 << endl;

	//指定位置删除
	s2.erase(2, 2);
	cout << s2 << endl;

	cout << "****测试用例结束****" << endl << endl;
}

//【笔记】
//泛型编程：使用模版编写和类型无关的代码
	//补充
		//在写模版代码时，函数需要传未知参数是，建议采用传引用且const修饰
		//在模版类的类外定义函数时要再次template<class T>,然后在增加 类<T>:: 说明函数归属
	//引用传参的场景：1.需要修改传递实参 2.减少拷贝
	//引用传返回值的场景：1.需要修改返回对象本身而非返回对象拷贝 2.减少拷贝
	//隐式实例化：T的类型由编译器自己推导
	//显示实例化：T的类型由自己指定
	
//****C++基础语法入门学习完成进入初阶****
 
//【初阶】10.STL+string
	//STL:C++标准模版库
		//STL简介：C++标准库的组成部分，主要包含数据结构和算法
		//STL版本：原始版本、P.J.版本、RW版本、SGI版本
		//STL六大组件：仿函数、算法、迭代器、空间配置器、容器、配接器
			//其中容器就包括常见的数据结构
		//学习STL的三层：熟练使用-》了解底层原理-》根据需求改造 
	//string类:管理字符串的类
		//string->字符数组 
		//string创建的字符串字符串后插入字符使用 push_back、插入字符串使用append 
		// 同时还可使用+=实现插入字符或字符串
		// size()可以计算字符串的字符数
		// 使用[]实现字符串每个字符的遍历，类似C语言数组
		// 使用（const srting& str，size_t pos，size_t len）可以拷贝字符串指定位置开始指定长度的子串，当数量为string::npos时拷贝至终点
//【初阶】11.string(1)
	//三种字符串遍历方式
		//1. []
		//2.迭代器iterator
			//使用时从string::iterator引入创建一个该类型的变量定义为某个字符的开始 .begin()终止条件为 .end()
		//3.auto 配合for也可以实现遍历
		//*.另一种迭代器reverse_iterator 
			//可以实现反向遍历 .rbegin() | .rend()
		//*.const_iterator
			//可以视为iserator的重载，只读遍历，主要给传const string类型的参数来使用
		//*.const_reverse_iterator 
			//反向遍历的迭代器同理
	//capacity：用来计算当前字符串的空间容量  ,string的对象的存储空间在增容时大概是按1.5倍进行增容
	//clear：用来清空当前字符串内容，但不缩小空间
	//empty：判断字符串是否为空 
	//reserve：可以按指定大小开辟空间
	//resize：不光开辟指定大小空间，并可指定赋值 
		// 如resize(100,'x'),就是开辟100多的空间每个位置都赋值字符'x'// 但如果原位置已经有值则不会覆盖
	//尾部插入的三种方式push_back（字符）、append（字符串）、+=（字符||字符串）
	//指定位置插入 insert  指定位置删除erase  





